using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using Microsoft.Practices.CompositeUI;
using Microsoft.Practices.ObjectBuilder;
using SCSFContrib.CompositeUI.WPF.Activation;
using NUnit.Framework;
using Rhino.Mocks;

namespace SCSFContrib.CompositeUI.WPF.UnitTest.Activation
{
	[TestFixture]
	public sealed class FrameworkElementActivationStrategyTest : UnitTest
	{
		private FrameworkElementActivationStrategy _frameworkElementActivationStrategy;

		protected override void  SetUpCore()
		{
		 	 base.SetUpCore();
			_frameworkElementActivationStrategy = new FrameworkElementActivationStrategy();
		}

		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void BuildUp_ShouldThrowIfContextIsNull()
		{
			_frameworkElementActivationStrategy.BuildUp(null, typeof(string), "existing", "id");
		}

		[Test]
		public void BuildUp_ShouldDoNothingIfExistingIsntFrameworkElement()
		{
			IReadWriteLocator locator = Mocks.DynamicMock<IReadWriteLocator>();
			IBuilderContext context = Mocks.DynamicMock<IBuilderContext>();
			Expect.Call(context.Locator).Repeat.Never();
			Mocks.ReplayAll();

			_frameworkElementActivationStrategy.BuildUp(context, null, "not a FrameworkElement", "id");
		}

		[Test]
		public void BuildUp_ShouldAddFrameworkElementToActivationService()
		{
			FrameworkElement frameworkElement = new FrameworkElement();
			IFrameworkElementActivationService frameworkElementActivationService = Mocks.DynamicMock<IFrameworkElementActivationService>();
			frameworkElementActivationService.FrameworkElementAdded(frameworkElement);
			LastCall.Repeat.Once();
			WorkItem workItem = new TestableRootWorkItem();
			workItem.Services.Add(frameworkElementActivationService);
			IReadWriteLocator locator = Mocks.DynamicMock<IReadWriteLocator>();
			Expect.Call(locator.Get<WorkItem>(null)).IgnoreArguments().Repeat.Once().Return(workItem);
			IBuilderContext context = Mocks.DynamicMock<IBuilderContext>();
			Expect.Call(context.Locator).Repeat.Once().Return(locator);
			Mocks.ReplayAll();

			_frameworkElementActivationStrategy.BuildUp(context, null, frameworkElement, "id");
		}

		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void TearDown_ShouldThrowIfContextIsNull()
		{
			_frameworkElementActivationStrategy.TearDown(null, "item");
		}

		[Test]
		public void TearDown_ShouldDoNothingIfItemIsntFrameworkElement()
		{
			IReadWriteLocator locator = Mocks.DynamicMock<IReadWriteLocator>();
			IBuilderContext context = Mocks.DynamicMock<IBuilderContext>();
			Expect.Call(context.Locator).Repeat.Never();
			Mocks.ReplayAll();

			_frameworkElementActivationStrategy.TearDown(context, "not a FrameworkElement");
		}

		[Test]
		public void TearDown_ShouldRemoveFrameworkElementFromActivationService()
		{
			FrameworkElement frameworkElement = new FrameworkElement();
			IFrameworkElementActivationService frameworkElementActivationService = Mocks.DynamicMock<IFrameworkElementActivationService>();
			frameworkElementActivationService.FrameworkElementRemoved(frameworkElement);
			LastCall.Repeat.Once();
			WorkItem workItem = new TestableRootWorkItem();
			workItem.Services.Add(frameworkElementActivationService);
			IReadWriteLocator locator = Mocks.DynamicMock<IReadWriteLocator>();
			Expect.Call(locator.Get<WorkItem>(null)).IgnoreArguments().Repeat.Once().Return(workItem);
			IBuilderContext context = Mocks.DynamicMock<IBuilderContext>();
			Expect.Call(context.Locator).Repeat.Once().Return(locator);
			Mocks.ReplayAll();

			_frameworkElementActivationStrategy.TearDown(context, frameworkElement);
		}
	}
}
